/**
 * 
 */
package it.sportingnola.soccernotes;

import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Classe che contiene tutte le interazioni con il db
 * 
 * @author paolo casillo
 */
public class DbHelper {
    private static class DatabaseHelper extends SQLiteOpenHelper {
	DatabaseHelper(Context context) {
	    super(context, Const.DATABASE_NAME, null, DATABASE_VERSION);
	}

	/**
	 * La prima cosa da fare quando il db è creato è creare le tabelle dell'applicazione
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
	    db.execSQL("create table " + Const.Cronache.NAME + "(_id integer primary key autoincrement, "
		+ Const.Cronache.KEY_TITLE + " text not null, " + Const.Cronache.KEY_BODY + " text not null, "
		+ Const.Cronache.KEY_TEAM1 + " text not null, " + Const.Cronache.KEY_REFEREE + " text not null, "
		+ Const.Cronache.KEY_RESULT + " text not null, " + Const.Cronache.KEY_ASSISTENTS + " text null, "
		+ Const.Cronache.KEY_TEAM2 + " text not null, " + Const.Cronache.KEY_PLACE + " text not null, "
		+ Const.Cronache.KEY_MATCH_DATE + " text not null," + Const.Cronache.KEY_CORNER1
		+ " integer not null default 0, " + Const.Cronache.KEY_CORNER2 + " integer not null default 0, "
		+ Const.Cronache.KEY_FOUL1 + " integer not null default 0, " + Const.Cronache.KEY_FOUL2
		+ " integer not null default 0, " + Const.Cronache.KEY_PLAYER_NR + " integer not null default 0);");
	    db.execSQL("create table " + Const.Players.NAME + "(_id integer primary key autoincrement, "
		+ Const.Players.KEY_CRONACA + " integer not null, " + Const.Players.KEY_NR + " string not null, "
		+ Const.Players.KEY_NAME + " text not null, " + Const.Players.KEY_TEAM + " integer not null,"
		+ Const.Players.KEY_IS_MR + " integer not null default 0," + Const.Players.KEY_IS_FC
		+ " integer not null default 1);");
	    db.execSQL("create table " + Const.Subst.NAME + "(_id integer primary key autoincrement, "
		+ Const.Subst.KEY_CRONACA + " integer not null, " + Const.Subst.KEY_PLAYER_IN + " integer not null, "
		+ Const.Subst.KEY_PLAYER_OUT + " integer not null, " + Const.Subst.KEY_MIN + " string not null, "
		+ Const.Subst.KEY_HALF + " integer not null, " + Const.Subst.KEY_TEAM + " integer not null);");
	    db.execSQL("create table " + Const.Actions.NAME + "(_id integer primary key autoincrement, "
		+ Const.Actions.KEY_CRONACA + " integer not null, " + Const.Actions.KEY_DESCRI + " string not null, "
		+ Const.Actions.KEY_MIN + " string not null, " + Const.Actions.KEY_HALF + " integer not null, "
		+ Const.Actions.KEY_TEAM + " integer null);");
	    db.execSQL("create table " + Const.Cards.NAME + "(_id integer primary key autoincrement, "
		+ Const.Cards.KEY_CRONACA + " integer not null, " + Const.Cards.KEY_PLAYER + " integer not null, "
		+ Const.Cards.KEY_MIN + " string not null, " + Const.Cards.KEY_HALF + " integer not null, "
		+ Const.Cards.KEY_CARD + " integer not null," + Const.Cards.KEY_REASON + " string null,"
		+ Const.Cards.KEY_TEAM + " integer null);");
	    db.execSQL("create table " + Const.Goals.NAME + "(_id integer primary key autoincrement, "
		+ Const.Goals.KEY_CRONACA + " integer not null, " + Const.Goals.KEY_PLAYER + " integer not null, "
		+ Const.Goals.KEY_MIN + " string not null, " + Const.Goals.KEY_IS_AUTO + " integer not null, "
		+ Const.Goals.KEY_IS_PENALTY + " integer not null, " + Const.Goals.KEY_HALF + " integer not null, "
		+ Const.Goals.KEY_TEAM + " integer not null);");
	    db.execSQL("create table " + Const.Config.NAME + "(" + Const.Config.KEY_MAIL_TO + " string not null, "
		+ Const.Config.KEY_MAIL_FROM + " string not null, " + Const.Config.KEY_DEFAULT_PL_NUMBER
		+ " integer not null);");
	    ContentValues args=new ContentValues();
	    args.put(Const.Config.KEY_DEFAULT_PL_NUMBER, 0);
	    args.put(Const.Config.KEY_MAIL_TO, "info@soccer-notes.com");
	    args.put(Const.Config.KEY_MAIL_FROM, "info@soccer-notes.com");
	    db.insert(Const.Config.NAME, null, args);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

	}
    }

    public static final String KEY_TITOLI="TITOLI";
    private DatabaseHelper mDbHelper;

    private SQLiteDatabase mDb;

    private static final int DATABASE_VERSION=3;

    private final Context mCtx;

    /**
     * Il costruttore - prende il contesto per permettergli di creare / aprire il db
     * 
     * @param ctx : il contesto in cui lavorare
     */
    public DbHelper(Context ctx) {
	this.mCtx=ctx;

    }

    /**
     * Verifica se sono stati inseriti i giocatori di entrambe le squadre
     * 
     * @param cronaca : la cronaca da controllare
     * @return true se ci sono giocatori per entrambe le squadre, false altrimenti
     */
    public boolean areThereAllPlayer(Long cronaca) {
	if (cronaca == null) {
	    return false;
	}
	if ( ! areThereAnyPlayer(cronaca, Const.HOME_TEAM)) {
	    return false;
	}
	return areThereAnyPlayer(cronaca, Const.FOREIGN_TEAM);
    }

    /**
     * Verifica se ci sono i giocatori di una squadra
     * 
     * @param cronaca
     * @param team
     * @return
     */
    public boolean areThereAnyPlayer(Long cronaca, int team) {
	if (cronaca == null) {
	    return false;
	}
	Cursor c=mDb.query(Const.Players.NAME, new String[]{Const.Players.KEY_ROWID }, Const.Players.KEY_CRONACA + "="
	    + cronaca + " AND " + Const.Players.KEY_TEAM + "=" + team, null, null, null, null);
	boolean ret=c.moveToFirst();
	c.close();
	return ret;
    }

    /**
     * Cancella l'azione selezionata
     * 
     * @param rowId: l'id dell'azione
     */
    public void cancellaAction(long rowId) {
	mDb.delete(Const.Actions.NAME, Const.Actions.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Cancella il cartellino
     * 
     * @param rowId: l'id del cartellino
     */
    public void cancellaCard(long rowId) {
	mDb.delete(Const.Cards.NAME, Const.Cards.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Cancella il goal
     * 
     * @param rowId: l'id del goal
     */
    public void cancellaGoal(long rowId) {
	mDb.delete(Const.Goals.NAME, Const.Goals.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Cancella la sostituzione
     * 
     * @param rowId: l'id della sostituzione
     */
    public void cancellaSubst(long rowId) {
	mDb.delete(Const.Subst.NAME, Const.Subst.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Cerca le azioni di una cronaca
     * 
     * @param cronaca: l'id della cronaca
     * @return
     */
    public Cursor cercaAction(long cronaca) {
	return mDb.rawQuery("SELECT " + Const.Actions.KEY_ROWID + ", " + Const.Actions.KEY_TEAM + ", "
	    + Const.Actions.KEY_HALF + ", " + Const.Actions.KEY_DESCRI + "," + Const.Actions.KEY_MIN + " FROM "
	    + Const.Actions.NAME + " WHERE " + Const.Actions.KEY_CRONACA + "=" + cronaca + " ORDER BY "
	    + Const.Actions.KEY_ROWID + " DESC", null);
    }

    /**
     * Cerca tutti i cartellini di una cronaca
     * 
     * @param cronaca: l'id della cronaca
     * @return
     */
    public Cursor cercaCard(long cronaca) {
	return mDb.rawQuery("SELECT c._id AS " + Const.Cards.KEY_ROWID + ", p." + Const.Players.KEY_NAME + " AS "
	    + Const.Cards.KEY_NAME_PLAYER + ", c." + Const.Cards.KEY_TEAM + " AS " + Const.Cards.KEY_TEAM + ", "
	    + Const.Cards.KEY_HALF + ", " + Const.Cards.KEY_CARD + "," + Const.Cards.KEY_REASON + ","
	    + Const.Cards.KEY_MIN + " FROM " + Const.Cards.NAME + " AS c JOIN " + Const.Players.NAME + " AS p ON "
	    + Const.Cards.KEY_PLAYER + "=p." + Const.Players.KEY_ROWID + " WHERE c." + Const.Players.KEY_CRONACA + "="
	    + cronaca + " ORDER BY c." + Const.Cards.KEY_ROWID + " DESC", null);
    }

    /**
     * Recupera dal db i parametri i configurazione
     * 
     * @return Un cursore con i parametri
     */
    public Cursor cercaConfig() {
	return mDb.query(Const.Config.NAME, Const.Config.ALL_FIELDS, null, null, null, null, null);
    }

    /**
     * Cerca i goal di una cronaca
     * 
     * @param cronaca: l'id della cronaca
     * @return
     */
    public Cursor cercaGoal(long cronaca) {
	return mDb.rawQuery("SELECT g._id AS " + Const.Goals.KEY_ROWID + ", p." + Const.Players.KEY_NAME + " AS "
	    + Const.Goals.KEY_NAME_PLAYER + ", g." + Const.Goals.KEY_TEAM + " AS " + Const.Goals.KEY_TEAM + ", "
	    + Const.Goals.KEY_HALF + ", " + Const.Goals.KEY_IS_AUTO + "," + Const.Goals.KEY_MIN + ","
	    + Const.Goals.KEY_IS_PENALTY + " FROM " + Const.Goals.NAME + " AS g JOIN " + Const.Players.NAME
	    + " AS p ON " + Const.Goals.KEY_PLAYER + "=p." + Const.Players.KEY_ROWID + " WHERE g."
	    + Const.Players.KEY_CRONACA + "=" + cronaca + " ORDER BY g." + Const.Goals.KEY_ROWID + " DESC", null);
    }

    /**
     * Verifica se esiste in archivio una squadra con il dato nome
     * 
     * @param nomeSquadra
     * @return un cursors con id della cronache e i nomi delle due squadre
     */
    private Cursor cercaOldCronaca(String nomeSquadra, Long actCronaca) {
	return mDb.query(Const.Cronache.NAME, new String[]{Const.Cronache.KEY_ROWID, Const.Cronache.KEY_TEAM1,
	    Const.Cronache.KEY_TEAM2 }, "(" + Const.Cronache.KEY_TEAM1 + "=?" + " OR " + Const.Cronache.KEY_TEAM2
	    + "=?) AND " + Const.Cronache.KEY_ROWID + "<>?",
	    new String[]{nomeSquadra, nomeSquadra, actCronaca.toString() }, null, null, Const.Cronache.KEY_ROWID
		+ " DESC");
    }

    /**
     * Cerca i giocatori di una certa squadra
     * 
     * @param squadra: 1 (squadra di casa) o 2 (squadra in trasferta)
     * @param cronaca: l'id della cronaca per la quale cerchiamo la formazione
     * @return un cursore che contiente DbConst.players.MAX_PLAYERS righe
     */
    public Cursor cercaSquadra(short squadra, long cronaca) {
	return mDb.query(Const.Players.NAME, Const.Players.ALL_FIELDS, Const.Players.KEY_CRONACA + "=" + cronaca
	    + " AND " + Const.Players.KEY_TEAM + "=" + squadra, null, null, null, Const.Players.KEY_ROWID + " ASC");
    }

    /**
     * Cerca le sostituzioni di una cronaca
     * 
     * @param cronaca: l'id della cronaca
     * @return
     */
    public Cursor cercaSubst(long cronaca) {
	return mDb.rawQuery("SELECT s._id AS " + Const.Subst.KEY_ROWID + ",s." + Const.Subst.KEY_TEAM + " AS "
	    + Const.Subst.KEY_TEAM + ", team_in." + Const.Players.KEY_NAME + " AS " + Const.Subst.KEY_NAME_PLAYER_IN
	    + ", team_out." + Const.Players.KEY_NAME + " AS " + Const.Subst.KEY_NAME_PLAYER_OUT + ", "
	    + Const.Subst.KEY_HALF + "," + Const.Subst.KEY_MIN + " FROM " + Const.Subst.NAME + " AS s, "
	    + Const.Players.NAME + " AS team_in, " + Const.Players.NAME + " AS team_out WHERE "
	    + Const.Subst.KEY_PLAYER_IN + "=team_in._id AND " + Const.Subst.KEY_PLAYER_OUT + "=team_out._id AND s."
	    + Const.Players.KEY_CRONACA + "=" + cronaca + " ORDER BY s." + Const.Subst.KEY_ROWID + " DESC", null);
    }

    /**
     * Funzione utile per l'autocomplete dei campi delle squadra: cerca tra entrambi i campi
     * "squadra" delle vecchie cronache
     * 
     * @param constr: la stringa di ricerca
     * @return: una lista di stringhe
     */
    public List<String> cercaVecchieSquadre(String constr) {
	List<String> ret=new ArrayList<String>();
	Cursor c=mDb.rawQuery("SELECT team1 FROM " + Const.Cronache.NAME + " where team1 like '" + constr
	    + "%' UNION Select team2 from " + Const.Cronache.NAME + " where team2 like '" + constr + "%'", null);
	if (c.moveToFirst()) {
	    do {
		if ( ! ret.contains(c.getString(0))) {
		    ret.add(c.getString(0));
		    if (ret.size() == Const.MAX_SUGGESTIONS) {
			break;
		    }
		}
	    }
	    while (c.moveToNext());
	}
	c.close();
	return ret;
    }

    /**
     * Chiude la connessione con il db
     */
    public void close() {
	mDbHelper.close();
    }

    /**
     * Crea una nuova cronaca usando le informazioni passate. Se la nota è creata con successo
     * restituisce l'id della nuova cronaca, altrimenti dà -1
     * 
     * @param title: il titolo della cronaca
     * @param notes: le note
     * @param result: il risultato
     * @param referee: l'arbitro
     * @param assistents: gli assistenti
     * @param place: il uogo
     * @param nrPlayers: il numero di giocatori
     * @team1: il nome della squadra di casa
     * @team2: il nome della squadra in trasferta
     * @md: la data dell'incontro
     * @return l'id della cronaca o -1
     */
    public long createNote(String title, String notes, String result, String place, Long nrPlayers, int foul1,
	int foul2, int corner1, int corner2) {
	ContentValues args=new ContentValues();
	args.put(Const.Cronache.KEY_TITLE, title);
	args.put(Const.Cronache.KEY_BODY, notes);
	args.put(Const.Cronache.KEY_MATCH_DATE, "");
	args.put(Const.Cronache.KEY_TEAM1, "");
	args.put(Const.Cronache.KEY_TEAM2, "");
	args.put(Const.Cronache.KEY_ASSISTENTS, "");
	args.put(Const.Cronache.KEY_REFEREE, "");
	args.put(Const.Cronache.KEY_RESULT, result);
	args.put(Const.Cronache.KEY_PLACE, place);
	args.put(Const.Cronache.KEY_PLAYER_NR, nrPlayers);
	args.put(Const.Cronache.KEY_FOUL1, foul1);
	args.put(Const.Cronache.KEY_FOUL2, foul2);
	args.put(Const.Cronache.KEY_CORNER1, corner1);
	args.put(Const.Cronache.KEY_CORNER2, corner2);
	return mDb.insert(Const.Cronache.NAME, null, args);
    }

    /**
     * Cancella una nota con chiave rowId
     * 
     * @param rowId : id della cronaca da cancellare
     * @return true se cancellata, false altrimenti
     */
    public boolean deleteNote(long rowId) {
	return mDb.delete(Const.Cronache.NAME, Const.Cronache.KEY_ROWID + "=" + rowId, null) > 0;
    }

    /**
     * Restituisce un Cursor che si muove sulla lista di tutte le cronache in db
     * 
     * @return Cursor delle cronache
     */
    public Cursor fetchAllNotes() {
	return mDb.query(Const.Cronache.NAME, Const.Cronache.ALL_FIELDS, null, null, null, null, null);
    }

    /**
     * Resituisce un elenco di titoli
     * 
     * @return
     */
    public Cursor fetchAllTitles() {
	return mDb.rawQuery("SELECT " + Const.Cronache.KEY_ROWID + ", " + Const.Cronache.KEY_TEAM1 + "|| ' - ' || "
	    + Const.Cronache.KEY_TEAM2 + " || ' = ' || " + Const.Cronache.KEY_RESULT + " AS " + KEY_TITOLI + " FROM "
	    + Const.Cronache.NAME + " ORDER BY " + Const.Cronache.KEY_ROWID + " DESC", null);
    }

    /**
     * Restituisce tutti i giocatori di una squadra e di una cronaca, sulla base dei filtri
     * 
     * @param cronaca: la cronaca cui si fa riferimento
     * @param squadra: 0 o 1
     * @param is_from_bench: se true mostra prima i panchinari
     * @param filter_mister: se true non mostra l'allenatore
     * @return un cursore con la coppia _id - (nr + nome del giocatore) ordinato sulla base del
     *         campo IS_FC e NR; può filtrare l'allenatore.
     */
    public Cursor getAllPlayers(long cronaca, int squadra, boolean is_from_bench, boolean filter_mister) {
	String order=is_from_bench ? " ASC," : " DESC,";
	String filtroMister=filter_mister ? " AND " + Const.Players.KEY_IS_MR + "=0" : "";
	return mDb.rawQuery("Select " + Const.Players.KEY_ROWID + ", " + Const.Players.KEY_NR + "||' - '||"
	    + Const.Players.KEY_NAME + " AS " + Const.Players.KEY_NAME + " FROM " + Const.Players.NAME + " WHERE "
	    + Const.Players.KEY_CRONACA + "=" + cronaca + " AND " + Const.Players.KEY_TEAM + "=" + squadra
	    + filtroMister + " ORDER BY " + Const.Players.KEY_IS_FC + order + Const.Players.KEY_NR + " ASC", null);
    }

    /**
     * Recupera l'ultima azione salvata
     * 
     * @param cronaca
     * @return
     */
    public Cursor getLastAction(long cronaca) {
	Cursor ret=mDb.query(Const.Actions.NAME, Const.Actions.ALL_FIELDS, Const.Actions.KEY_CRONACA + "=" + cronaca,
	    null, null, null, null);
	if ( ! ret.moveToFirst()) {
	    return null;
	}
	else {
	    return ret;
	}
    }

    /**
     * Inserimento nel db dell'azione
     * 
     * @param team: 0 o 1
     * @param half: 0,1,2,3 o4
     * @param min: il minuto
     * @param cronaca: la cronaca cui appartiene la cronaca
     * @param descri: la descrizione della cronaca
     */
    public void insertAction(int team, int half, String min, long cronaca, String descri) {
	ContentValues args=new ContentValues();
	args.put(Const.Actions.KEY_DESCRI, descri);
	args.put(Const.Actions.KEY_CRONACA, cronaca);
	args.put(Const.Actions.KEY_HALF, half);
	args.put(Const.Actions.KEY_MIN, min);
	args.put(Const.Actions.KEY_TEAM, team);
	mDb.insert(Const.Actions.NAME, null, args);
    }

    /**
     * Inserimento di un cartellino
     * 
     * @param player
     * @param team
     * @param half
     * @param min
     * @param cronaca
     * @param motivo
     * @param card
     */
    public void insertCard(long player, int team, int half, String min, long cronaca, String motivo, int card) {
	ContentValues args=new ContentValues();
	args.put(Const.Cards.KEY_PLAYER, player);
	args.put(Const.Cards.KEY_REASON, motivo);
	args.put(Const.Cards.KEY_CRONACA, cronaca);
	args.put(Const.Cards.KEY_HALF, half);
	args.put(Const.Cards.KEY_MIN, min);
	args.put(Const.Cards.KEY_TEAM, team);
	args.put(Const.Cards.KEY_CARD, card);
	mDb.insert(Const.Cards.NAME, null, args);
    }

    /**
     * Inserimento di un goal
     * 
     * @param player
     * @param team
     * @param half
     * @param min
     * @param cronaca
     * @param isAuto
     * @param isRigore
     */
    public void insertGoal(long player, int team, int half, String min, long cronaca, boolean isAuto, boolean isRigore) {
	ContentValues args=new ContentValues();
	int isAutoNum=isAuto ? 1 : 0;
	int isRigNum=isRigore ? 1 : 0;
	args.put(Const.Goals.KEY_PLAYER, player);
	args.put(Const.Goals.KEY_IS_AUTO, isAutoNum);
	args.put(Const.Goals.KEY_CRONACA, cronaca);
	args.put(Const.Goals.KEY_HALF, half);
	args.put(Const.Goals.KEY_MIN, min);
	args.put(Const.Goals.KEY_TEAM, team);
	args.put(Const.Goals.KEY_IS_PENALTY, isRigNum);
	mDb.insert(Const.Goals.NAME, null, args);
    }

    /**
     * Inserimento di una sostituzione
     * 
     * @param player_in
     * @param player_out
     * @param team
     * @param half
     * @param min
     * @param cronaca
     */
    public void insertSubst(long player_in, long player_out, int team, int half, String min, long cronaca) {
	ContentValues args=new ContentValues();
	args.put(Const.Subst.KEY_PLAYER_IN, player_in);
	args.put(Const.Subst.KEY_PLAYER_OUT, player_out);
	args.put(Const.Subst.KEY_CRONACA, cronaca);
	args.put(Const.Subst.KEY_HALF, half);
	args.put(Const.Subst.KEY_MIN, min);
	args.put(Const.Subst.KEY_TEAM, team);
	mDb.insert(Const.Subst.NAME, null, args);
    }

    /**
     * Open the notes database. If it cannot be opened, try to create a new instance of the
     * database. If it cannot be created, throw an exception to signal the failure
     * 
     * @return this (self reference, allowing this to be chained in an initialization call)
     * @throws SQLException if the database could be neither opened or created
     */
    public DbHelper open() throws SQLException {
	mDbHelper=new DatabaseHelper(mCtx);
	mDb=mDbHelper.getWritableDatabase();
	return this;
    }

    /**
     * Recupera una singola azione
     * 
     * @param id: l'id dell'azione
     * @return
     */
    public Cursor recuperaAction(long id) {
	return mDb.query(Const.Actions.NAME, Const.Actions.ALL_FIELDS, Const.Actions.KEY_ROWID + "=" + id, null, null,
	    null, null);
    }

    /**
     * recupera il singolo cartellino
     * 
     * @param id: l'id del cartellino
     * @return
     */
    public Cursor recuperaCard(long id) {
	return mDb.query(Const.Cards.NAME, Const.Cards.ALL_FIELDS, Const.Cards.KEY_ROWID + "=" + id, null, null, null,
	    null);
    }

    /**
     * Recupera tutti i dati relativi ad una cronaca
     * 
     * @param id: l'id della cronaca
     * @return un cursore con la cronaca
     */
    public Cursor recuperaCronaca(Long id) {
	return mDb.query(Const.Cronache.NAME, Const.Cronache.ALL_FIELDS, Const.Cronache.KEY_ROWID + "=" + id, null,
	    null, null, null);
    }

    public Cursor recuperaGoal(long id) {
	return mDb.query(Const.Goals.NAME, Const.Goals.ALL_FIELDS, Const.Goals.KEY_ROWID + "=" + id, null, null, null,
	    null);
    }

    public Cursor recuperaSubst(long id) {
	return mDb.query(Const.Subst.NAME, Const.Subst.ALL_FIELDS, Const.Subst.KEY_ROWID + "=" + id, null, null, null,
	    null);
    }

    public String recuperaTitolo(long id) {
	String ret=null;
	Cursor c=mDb.rawQuery("SELECT " + Const.Cronache.KEY_TEAM1 + "|| ' - ' || " + Const.Cronache.KEY_TEAM2
	    + " || ' ' || " + Const.Cronache.KEY_RESULT + " AS " + KEY_TITOLI + " FROM " + Const.Cronache.NAME
	    + " WHERE " + Const.Cronache.KEY_ROWID + "=" + id, null);
	if (c.moveToFirst()) {
	    ret=c.getString(c.getColumnIndex(KEY_TITOLI));
	}
	c.close();
	return ret;
    }

    /**
     * Funzione di utilità che crea una squadra di default e resituisce un cursore che punta alla
     * squadra appena creata. Cerca, sulla base del nome della squadra, l'esistenza di precedenti
     * righe nel db: se esistono, copia i valori dell'ultima cronaca nella nuova, altrimenti salva
     * valori di default (numeri da 1 a nrPlayers e nomi vuoti)
     * 
     * @param squadra: 0 o 1
     * @param cronaca: la cronaca in cui salvare la squadra
     * @param nomeSquadra: il nome della squadra
     * @param nrPlayers: il numero di giocatori da inserire
     * @return
     */
    public Cursor riempiSquadra(short squadra, long cronaca, String nomeSquadra, int nrPlayers) {
	Cursor oldCronaca=cercaOldCronaca(nomeSquadra, cronaca); // cerco nelle altre cronache
	Cursor players=null; // il cursore dove saranno salvati i vecchi giocatori
	boolean giocatoriPresenti=false;
	if (oldCronaca.moveToFirst()) {
	    // c'era già una cronaca che parlava della stessa squadra => cerco la cronaca con i
	    // giocatori impostati
	    do {
		short oldTeam=nomeSquadra.equals(oldCronaca.getString(oldCronaca
		    .getColumnIndex(Const.Cronache.KEY_TEAM1))) ? Const.HOME_TEAM : Const.FOREIGN_TEAM;
		// carico i giocatori della vecchia squadra
		players=cercaSquadra(oldTeam, oldCronaca.getLong(oldCronaca.getColumnIndex(Const.Cronache.KEY_ROWID)));
		if (players.moveToFirst()) {
		    // l'ho trovata!
		    giocatoriPresenti=true;
		    break;
		}
	    }
	    while (oldCronaca.moveToNext());
	}
	if (giocatoriPresenti) {
	    // caso a: c'era già una squadra salvata
	    int i=1;
	    do {
		/**
		 * Abbio 3 casi possibili:
		 * <ul>
		 * <li>a1) Il numero di giocatori vecchio è uguale a quello attuale => nessun
		 * problema
		 * <li>a2) i vecchi giocatori sono in numero inferiore a quello attuale => devo
		 * riempire con giocatori di default</li>
		 * <li>a3) il vecchi giocatori sono in numero superiore a quello attuale => arrivato
		 * a nrPlayers mi devo fermare e copiare direttamente il mister
		 */
		ContentValues args=new ContentValues();
		if (players.getShort(players.getColumnIndex(Const.Players.KEY_IS_MR)) == 1) {
		    // sono nel caso a2) => procedo al riempimento
		    for (; i <= nrPlayers; i++) {
			args.put(Const.Players.KEY_CRONACA, cronaca);
			args.put(Const.Players.KEY_NAME, "");
			args.put(Const.Players.KEY_NR, i);
			args.put(Const.Players.KEY_IS_MR, 0);
			args.put(Const.Players.KEY_IS_FC, 0);
			args.put(Const.Players.KEY_TEAM, squadra);
			mDb.insert(Const.Players.NAME, null, args);
		    }
		    // quindi prendo il mister e ho finito
		    args.put(Const.Players.KEY_CRONACA, cronaca);
		    args.put(Const.Players.KEY_TEAM, squadra);
		    args.put(Const.Players.KEY_NAME, players.getString(players.getColumnIndex(Const.Players.KEY_NAME)));
		    args.put(Const.Players.KEY_NR, players.getString(players.getColumnIndex(Const.Players.KEY_NR)));
		    args.put(Const.Players.KEY_IS_MR, players.getShort(players.getColumnIndex(Const.Players.KEY_IS_MR)));
		    args.put(Const.Players.KEY_IS_FC, players.getShort(players.getColumnIndex(Const.Players.KEY_IS_FC)));
		    mDb.insert(Const.Players.NAME, null, args);
		}
		else {
		    args.put(Const.Players.KEY_CRONACA, cronaca);
		    args.put(Const.Players.KEY_TEAM, squadra);
		    args.put(Const.Players.KEY_NAME, players.getString(players.getColumnIndex(Const.Players.KEY_NAME)));
		    args.put(Const.Players.KEY_NR, players.getString(players.getColumnIndex(Const.Players.KEY_NR)));
		    args.put(Const.Players.KEY_IS_MR, players.getShort(players.getColumnIndex(Const.Players.KEY_IS_MR)));
		    args.put(Const.Players.KEY_IS_FC, players.getShort(players.getColumnIndex(Const.Players.KEY_IS_FC)));
		    mDb.insert(Const.Players.NAME, null, args);
		}
		if (i == nrPlayers) {
		    // ho caricato l'ultimo giocatore: devo caricare il mister e ho finito
		    // va bene sia nel caso a1 (il c.moveToLast() equivale ad un c.moveToNext()) sia
		    // al caso a2 (in quel caso il c.moveToLast() salta i giocatori in più)
		    players.moveToLast();
		    args=new ContentValues();
		    args.put(Const.Players.KEY_CRONACA, cronaca);
		    args.put(Const.Players.KEY_TEAM, squadra);
		    args.put(Const.Players.KEY_NAME, players.getString(players.getColumnIndex(Const.Players.KEY_NAME)));
		    args.put(Const.Players.KEY_NR, players.getString(players.getColumnIndex(Const.Players.KEY_NR)));
		    args.put(Const.Players.KEY_IS_MR, players.getShort(players.getColumnIndex(Const.Players.KEY_IS_MR)));
		    args.put(Const.Players.KEY_IS_FC, players.getShort(players.getColumnIndex(Const.Players.KEY_IS_FC)));
		    mDb.insert(Const.Players.NAME, null, args);
		    break;
		}
		i++;
	    }
	    while (players.moveToNext());
	}
	else {
	    int toInsert=nrPlayers + 1; // devo inseriro n+1 righe (n=nr giocatori + l'allenatore)
	    for (int i=1; i <= toInsert; i++) {
		ContentValues args=new ContentValues();
		args.put(Const.Players.KEY_CRONACA, cronaca);
		args.put(Const.Players.KEY_NAME, "");
		if (i != toInsert) {
		    args.put(Const.Players.KEY_NR, i);
		    args.put(Const.Players.KEY_IS_MR, 0);
		    if (i < Const.NR_TITOLARI) {
			args.put(Const.Players.KEY_IS_FC, 1);
		    }
		    else {
			args.put(Const.Players.KEY_IS_FC, 0);
		    }
		}
		else {
		    args.put(Const.Players.KEY_NR, mCtx.getString(R.string.coach));
		    args.put(Const.Players.KEY_IS_MR, 0);
		}
		args.put(Const.Players.KEY_TEAM, squadra);
		mDb.insert(Const.Players.NAME, null, args);
	    }
	}
	Cursor ret=cercaSquadra(squadra, cronaca);
	return ret;
    }

    /**
     * Aggiornamento dell'azione
     * 
     * @param rowId
     * @param team
     * @param half
     * @param min
     * @param cronaca
     * @param descri
     */
    public void updateAction(long rowId, int team, int half, String min, long cronaca, String descri) {
	ContentValues args=new ContentValues();
	args.put(Const.Actions.KEY_CRONACA, cronaca);
	args.put(Const.Actions.KEY_DESCRI, descri);
	args.put(Const.Actions.KEY_TEAM, team);
	args.put(Const.Actions.KEY_HALF, half);
	args.put(Const.Actions.KEY_MIN, min);
	mDb.update(Const.Actions.NAME, args, Const.Actions.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Aggiornamento del cartellino
     * 
     * @param rowId
     * @param player
     * @param team
     * @param half
     * @param min
     * @param cronaca
     * @param motivo
     * @param card
     */
    public void updateCard(long rowId, long player, int team, int half, String min, long cronaca, String motivo,
	int card) {
	ContentValues args=new ContentValues();
	args.put(Const.Cards.KEY_CRONACA, cronaca);
	args.put(Const.Cards.KEY_PLAYER, player);
	args.put(Const.Cards.KEY_REASON, motivo);
	args.put(Const.Cards.KEY_TEAM, team);
	args.put(Const.Cards.KEY_HALF, half);
	args.put(Const.Cards.KEY_MIN, min);
	args.put(Const.Cards.KEY_CARD, card);
	mDb.update(Const.Cards.NAME, args, Const.Goals.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Aggiornamento della configurazione
     * 
     * @param nrPl
     * @param mailTo
     * @param mailFrom
     */
    public void updateConfig(long nrPl, String mailTo, String mailFrom) {
	ContentValues args=new ContentValues();
	args.put(Const.Config.KEY_DEFAULT_PL_NUMBER, nrPl);
	args.put(Const.Config.KEY_MAIL_FROM, mailFrom);
	args.put(Const.Config.KEY_MAIL_TO, mailTo);
	mDb.update(Const.Config.NAME, args, null, null);

    }

    /**
     * Aggiornamento del goal
     * 
     * @param rowId
     * @param player
     * @param team
     * @param half
     * @param min
     * @param cronaca
     * @param isAuto
     * @param isRigore
     */
    public void updateGoal(long rowId, long player, int team, int half, String min, long cronaca, boolean isAuto,
	boolean isRigore) {
	ContentValues args=new ContentValues();
	int isAutoNum=isAuto ? 1 : 0;
	int isRigNum=isRigore ? 1 : 0;
	args.put(Const.Goals.KEY_CRONACA, cronaca);
	args.put(Const.Goals.KEY_PLAYER, player);
	args.put(Const.Goals.KEY_IS_AUTO, isAutoNum);
	args.put(Const.Goals.KEY_TEAM, team);
	args.put(Const.Goals.KEY_HALF, half);
	args.put(Const.Goals.KEY_MIN, min);
	args.put(Const.Goals.KEY_IS_PENALTY, isRigNum);
	mDb.update(Const.Goals.NAME, args, Const.Goals.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Aggiorna la cronaca usando i dettagli forniti.
     * 
     * @param id della cronaca da aggiornare
     * @param title: il titolo
     * @param body: le note
     * @return
     */
    public boolean updateNote(long id, String title, String body, String date, String team1, String team2,
	String assistents, String referee, String result, String luogo, long nrPlayers, int corner1, int corner2,
	int foul1, int foul2) {
	ContentValues args=new ContentValues();
	args.put(Const.Cronache.KEY_TITLE, title.trim());
	args.put(Const.Cronache.KEY_BODY, body);
	args.put(Const.Cronache.KEY_MATCH_DATE, date);
	args.put(Const.Cronache.KEY_TEAM1, team1.trim());
	args.put(Const.Cronache.KEY_TEAM2, team2.trim());
	args.put(Const.Cronache.KEY_ASSISTENTS, assistents);
	args.put(Const.Cronache.KEY_REFEREE, referee);
	args.put(Const.Cronache.KEY_RESULT, result.trim());
	args.put(Const.Cronache.KEY_PLACE, luogo.trim());
	args.put(Const.Cronache.KEY_PLAYER_NR, nrPlayers);
	args.put(Const.Cronache.KEY_CORNER1, corner1);
	args.put(Const.Cronache.KEY_CORNER2, corner2);
	args.put(Const.Cronache.KEY_FOUL1, foul1);
	args.put(Const.Cronache.KEY_FOUL2, foul2);
	return mDb.update(Const.Cronache.NAME, args, Const.Cronache.KEY_ROWID + "=" + id, null) > 0;
    }

    /**
     * Aggiornamento di un giocatore
     * 
     * @param rowId: l'id del giocatore
     * @param squadra: 0 o 1
     * @param cronaca: la cronaca di appartenenza
     * @param nr: il numero di maglia
     * @param nome: il nome e cognome del giocatore
     * @param is_mr: 1 se è l'allenatore, 0 altrimenti
     * @param is_fc: 1 se è titolare, 0 altrimenti
     */
    public void updatePlayer(long rowId, short squadra, long cronaca, String nr, String nome, int is_mr, int is_fc) {
	ContentValues args=new ContentValues();
	args.put(Const.Players.KEY_CRONACA, cronaca);
	args.put(Const.Players.KEY_NAME, nome);
	args.put(Const.Players.KEY_NR, nr);
	args.put(Const.Players.KEY_TEAM, squadra);
	args.put(Const.Players.KEY_IS_FC, is_fc);
	args.put(Const.Players.KEY_IS_MR, is_mr);
	mDb.update(Const.Players.NAME, args, Const.Players.KEY_ROWID + "=" + rowId, null);
    }

    /**
     * Aggiornamento di una sostituzione
     * 
     * @param parseLong
     * @param player_in
     * @param player_out
     * @param team
     * @param half
     * @param min
     * @param cronaca
     */
    public void updateSubst(long rowId, long player_in, long player_out, int team, int half, String min, long cronaca) {
	ContentValues args=new ContentValues();
	args.put(Const.Subst.KEY_CRONACA, cronaca);
	args.put(Const.Subst.KEY_PLAYER_IN, player_in);
	args.put(Const.Subst.KEY_PLAYER_OUT, player_out);
	args.put(Const.Subst.KEY_TEAM, team);
	args.put(Const.Subst.KEY_HALF, half);
	args.put(Const.Subst.KEY_MIN, min);
	mDb.update(Const.Subst.NAME, args, Const.Subst.KEY_ROWID + "=" + rowId, null);
    }
}
